package qqserver.service;

import qqcommon.Message;
import qqcommon.MessageType;
import qqcommon.User;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;

/**
 * @author 王艺锡
 * @version 1.0
 * 服务端，监听9999端口，等待客户端连接
 */
public class QQServer {
    private ServerSocket serverSocket = null;
    //创建一个集合，用于保存合法的用户
    //这里可以使用ConcurrentHashMap，可以处理并发的集合
    //HashMap没有处理线程安全，因此在多线程情况下是不安全的
    //ConcurrentHashMap处理线程安全，即线程同步处理，在多线程的情况下是安全的
    private static HashMap<String, User> validUser = new HashMap<>();

    //创建一个静态的代码块，初始化合法用户
    static {
        validUser.put("100", new User("100", "123456"));
        validUser.put("200", new User("200", "123456"));
        validUser.put("300", new User("300", "123456"));
        validUser.put("王艺锡", new User("王艺锡", "1758567217"));
    }

    ;

    private static boolean checkUser(String userId, String pwd) {
        User user = validUser.get(userId);
        if (user == null) {//如果为空，说明对象不合法
            return false;
        }

        if (!(pwd.equals(user.getPasswd()))) {//如果密码错误,返回false
            return false;
        }
        return true;
    }

    public QQServer() {
        try {
            System.out.println("服务器端在9999端口监听...");
            serverSocket = new ServerSocket(9999);
            //开启服务端推送新闻的线程
            new Thread(new SendNews()).start();

            //因为连接服务端的用户不止一个，所以要用while循环进行循环接收
            //接收到客户端传来的User对象后，进行验证，如果通过则返回登陆成功信息并且开辟线程保持两边的通信，
            //如果验证不通过则返回登录失败信息
            while (true) {
                Socket socket = serverSocket.accept();
                ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
                User user = (User) ois.readObject();//读取客户端传来的User对象

                //判断对象是否合法，然后回复信息
                ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
                Message message = new Message();

                if (checkUser(user.getUserId(), user.getPasswd())) {//合法
                    message.setMesType(MessageType.MESSAGE_LOGIN_SUCCEED);
                    oos.writeObject(message);

                    //创建一个线程，和客户端保持连接
                    ServerConnectClientThread scct = new ServerConnectClientThread(socket, user.getUserId());

                    //把该线程放入一个集合中，方便管理
                    ManageServerConnectClientThread.addServerConnectClientThread(user.getUserId(), scct);
                    //启动线程
                    scct.start();




                } else {//不合法
                    System.out.println("用户" + user.getUserId() + "登录失败...");
                    message.setMesType(MessageType.MESSAGE_LOGIN_FAIL);
                    oos.writeObject(message);
                    //关闭对应的socket
                    socket.close();
                }

            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {//如果退出while循环，则关闭serverSocket
            try {
                serverSocket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }


    }


}
